package com.xdhl.fu.common.core.utils;

import javax.script.ScriptEngine;
import javax.script.ScriptEngineManager;
import javax.script.ScriptException;
import java.math.BigDecimal;
import java.math.RoundingMode;
import java.util.HashMap;
import java.util.Map;

/**
 * 数学工具类
 *
 * @author 朱力维
 */
public class MathUtils {

    /**
     * 小数点后的金额位数
     */
    public static final Integer COUNT_AFTER_DOT = 2;

    public static void main(String[] args) throws ScriptException {
        String script = "O*DtY/1000*1";
        Map<String, String> variables = new HashMap<>();
        variables.put("O", "117.40");
        variables.put("DtY", "6.6558");
        System.out.println(MathUtils.calcByScript(script, variables));
    }

    /**
     * 金额加法运算
     *
     * @param param 累加的数集合
     * @return 和
     */
    public static double priceAdd(double... param) {
        BigDecimal sumAdd = BigDecimal.valueOf(0);
        for (int i = 0; i < param.length; i++) {
            BigDecimal bigDecimal = BigDecimal.valueOf(param[i]);
            sumAdd = sumAdd.add(bigDecimal);
        }
        return sumAdd.setScale(COUNT_AFTER_DOT, RoundingMode.HALF_UP).doubleValue();
    }

    /**
     * 金额减法运算
     *
     * @param first 减数
     * @param last  被减数
     * @return 差
     */
    public static double priceSubtract(double first, double last) {
        return BigDecimal.valueOf(first).subtract(BigDecimal.valueOf(last)).setScale(COUNT_AFTER_DOT, RoundingMode.HALF_UP).doubleValue();
    }

    /**
     * 金额乘法法运算
     *
     * @param first 乘数
     * @param last  被乘数
     * @return 积
     */
    public static double priceMultip(double first, double last) {
        if (first == 0D || last == 0D) {
            return first;
        }
        return BigDecimal.valueOf(first).multiply(BigDecimal.valueOf(last)).setScale(COUNT_AFTER_DOT, RoundingMode.HALF_UP).doubleValue();
    }

    /**
     * 金额除法运算
     *
     * @param first 除数
     * @param last  被除数
     * @return 商
     */
    public static double priceDivide(double first, double last) {
        if (first == 0D || last == 0D) {
            return first;
        }
        return BigDecimal.valueOf(first).divide(BigDecimal.valueOf(last), RoundingMode.HALF_UP).doubleValue();
    }

    /**
     * 计算脚本公式
     *
     * @param script    脚本公式
     * @param variables 变量集合
     * @return 返回值
     * @throws ScriptException 脚本公式异常
     */
    public static Double calcByScript(String script, Map<String, String> variables) throws ScriptException {
        System.setProperty("nashorn.args", "--no-deprecation-warning");
        ScriptEngine jse = new ScriptEngineManager().getEngineByName("JavaScript");
        for (Map.Entry<String, String> variable : variables.entrySet()) {
            script = script.replaceAll(variable.getKey(), variable.getValue());
        }
        return (Double) jse.eval(script);
    }

}
